package top.chengdongqing.mishop.utils

import io.jsonwebtoken.Claims
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.SignatureAlgorithm
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
import top.chengdongqing.mishop.auth.Token
import java.security.Key
import java.util.*
import javax.crypto.spec.SecretKeySpec

/**
 * json web token工具类
 */
@Component
class JwtUtils(
    @Value("\${application.security.jwt.secret}") private val secret: String,
    @Value("\${application.security.jwt.expiration}") private val expiration: Long,
    @Value("\${application.security.jwt.refresh-token.expiration}") private val refreshTokenExpiration: Long
) {
    private val secretKey: Key = SecretKeySpec(secret.toByteArray(), SignatureAlgorithm.HS256.jcaName)

    fun generate(userId: Int): Token {
        val expiryDate = Date(System.currentTimeMillis() + expiration)
        val accessToken = generate(userId, expiryDate)
        val refreshToken = generate(userId, Date(System.currentTimeMillis() + refreshTokenExpiration))

        return Token(accessToken, refreshToken, expiryDate)
    }

    fun generateForRefresh(userId: Int, refreshTokenExpiryDate: Date): Token {
        val expiryDate = Date(System.currentTimeMillis() + expiration)
        val accessToken = generate(userId, expiryDate)
        val refreshToken = generate(userId, refreshTokenExpiryDate)

        return Token(accessToken, refreshToken, expiryDate)
    }

    private fun generate(userId: Int, expiryDate: Date): String {
        return Jwts.builder()
            .setIssuedAt(Date())
            .setExpiration(expiryDate)
            .setSubject(userId.toString())
            .signWith(secretKey)
            .compact()
    }

    fun parse(token: String): Claims {
        return Jwts.parserBuilder()
            .setSigningKey(secretKey)
            .build()
            .parseClaimsJws(token)
            .body
    }

    fun getUserId(token: String): Int {
        return parse(token).subject.toInt()
    }
}
